package com.ce.config;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @description: 文件工具
 * @author: jyt
 * @create: 2021-09-16 10:36
 **/
@Component
public class FileUtil {
    @Resource
    private MinioClient minioClient;

    /**
     * 上传文件
     *
     * @param multipartFile 文件
     * @param bucketName    桶名称
     * @return
     */
    public String upload(MultipartFile multipartFile, String bucketName) {
        String fileUrl = null;
        if (BeanUtil.isEmpty(multipartFile)) {
//            throw new FileException(FileExceptionEnum.FILE_DOES_NOT_EXIST);
            System.out.println("图片为空");
        }
        try {
            initializeTheBucket(bucketName);
            InputStream inputStream = multipartFile.getInputStream();
            int size = inputStream.available();
            String contentType = multipartFile.getContentType();
            String fileName = DateUtil.current() + StrUtil.uuid();
            minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, size, -1).contentType(contentType).build());
            fileUrl = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(fileName)
                            .expiry(1, TimeUnit.SECONDS).build()
            );
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StrUtil.isNotBlank(fileUrl)) {
            fileUrl = fileUrl.substring(0, fileUrl.indexOf("?"));
            return fileUrl;
        }
        return null;
    }

    /**
     * 初始化桶
     *
     * @param bucketName 桶名
     * @throws ServerException
     * @throws InsufficientDataException
     * @throws ErrorResponseException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws XmlParserException
     * @throws InternalException
     */
    public void initializeTheBucket(String bucketName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        if (!isBucket(bucketName)) {
            minioClient.makeBucket(
                    MakeBucketArgs.builder().bucket(bucketName).build()
            );
            minioClient.setBucketPolicy(
                    SetBucketPolicyArgs.builder().bucket(bucketName).config(bucketStrategy(bucketName)).build()
            );
        }
    }

    /**
     * 判断桶是否存在
     *
     * @param bucket
     * @return
     * @throws ServerException
     * @throws InsufficientDataException
     * @throws ErrorResponseException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws XmlParserException
     * @throws InternalException
     */
    private Boolean isBucket(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        boolean isBucket = minioClient.bucketExists(BucketExistsArgs.builder()
                .bucket(bucket).build());
        return isBucket;
    }

    /**
     * 自定义桶策略
     *
     * @param bucketName
     * @return
     */
    private String bucketStrategy(String bucketName) {
        String bucketUrl = "arn:aws:s3:::" + bucketName;
        Map<String, Object> map = new HashMap<>();
        List<String> actions = new ArrayList<>();
        actions.add("s3:GetObject");
        actions.add("s3:PutObject");
        actions.add("s3:DeleteObject");
        actions.add("s3:GetBucketLocation");
        List<Map<String, Object>> statements = new ArrayList<>();

        Map<String, Object> statement = new HashMap<>();
        statement.put("Action", actions);
        statement.put("Effect", "Allow");
        statement.put("Principal", "*");

        List<String> resourceList = new ArrayList<>();
        resourceList.add(bucketUrl);
        resourceList.add(bucketUrl + "/*");

        statement.put("Resource", resourceList);
        statements.add(statement);


        map.put("Statement", statements);
        map.put("Version", "2012-10-17");
        return JSON.toJSONString(map);
    }
}
